package com.tenebrous.jestic.chain;

import com.alibaba.fastjson.JSON;
import com.rain.ops.sdk.dto.ApiResult;
import com.tenebrous.jestic.auth.AuthTokenGenerator;
import com.tenebrous.jestic.compents.exception.BizException;
import com.tenebrous.jestic.context.JesticContext;
import com.tenebrous.jestic.context.JesticTask;
import com.tenebrous.jestic.context.Response;
import com.tenebrous.jestic.entity.model.request.JesticAuthorityRequest;
import com.tenebrous.jestic.entity.model.request.ServerHearBeatRequest;
import com.tenebrous.jestic.entity.model.response.JesticAuthorityResponse;
import com.tenebrous.jestic.entity.model.response.ServerHearBeatResponse;
import com.tenebrous.jestic.entity.server.JesticServer;
import com.tenebrous.jestic.enums.TaskStatus;
import com.tenebrous.jestic.server.AbstractInstanceContext;
import com.tenebrous.jestic.server.Instance;
import com.tenebrous.jestic.service.server.AuthServerService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

/**
 * @Description:
 * @Project: jestic-spring-boot
 * @Package: com.zy.tenebrous.jestic.chain
 * @Author: zhangya
 * @CreateTime: 2023-06-28  18:15
 * @Version: 1.0.0
 */
@Slf4j
@Service("JesticHeartBeatHandler")
public class JesticHeartBeatHandler extends AbstractJesticChainHandler<ServerHearBeatRequest, ServerHearBeatResponse> {

    @Resource
    private final AuthServerService authServerService;

    @Resource
    private final AbstractInstanceContext abstractInstanceContext;

    @Resource
    private final AuthTokenGenerator authToken;

    public JesticHeartBeatHandler(AuthServerService authServerService, AbstractInstanceContext abstractInstanceContext, AuthTokenGenerator authToken){
        this.authServerService = authServerService;
        this.abstractInstanceContext = abstractInstanceContext;
        this.authToken = authToken;
    }

    private  int order;

    @Override
    public void handler(JesticContext<? extends JesticTask, ? extends Response> context) {

        ServerHearBeatRequest request = (ServerHearBeatRequest) context.getRequest();
        log.info("JesticHeartBeatHandler.handler.start.request[{}]", JSON.toJSONString(request));
        ServerHearBeatResponse response = (ServerHearBeatResponse) context.getResponse();
        String serverName = request.getServerName();
        String serverId = request.getServerId();
        String instanceId = request.getInstanceId();

        JesticServer jesticServer = authServerService.selectServer(serverId, serverName);
        if (Objects.isNull(jesticServer)) {
            log.info("jestic [ServerServiceGrpcImpl.keepHeartBeat] client [{}] server not found", request.getServerName());
            response.setCode(500);
            response.setMessage("server not found");
            response.setResult(false);
        } else if (jesticServer.getServerStatus() != 1) {
            log.info("jestic [ServerServiceGrpcImpl.keepHeartBeat] client [{}] status  not abnormal", request.getServerName());
            response.setCode(500);
            response.setMessage("server status not is running");
            response.setResult(false);
        } else {
            log.info("jestic server accept client[{}] instance:[{}] send heartbeat packet, in healthy state", request.getServerName(), request.getInstanceId());
            Instance instance = abstractInstanceContext.getInstanceById(instanceId);
            if (Objects.isNull(instance)) {
                log.info("jestic server accept client[{}] instance:[{}] not fount, please try to Auth", request.getServerName(), request.getInstanceId());
                response.setCode(500);
                response.setMessage("server "+request.getServerName()+" instance not fount, please try to Auth");
                response.setResult(false);
            } else {
                // 维持心跳
                instance.setRecentlyAuth(new Date().getTime());
                instance.setTimes(instance.getTimes() + 1);
                abstractInstanceContext.flushInstance(instance);
                response.setCode(200);
                response.setMessage("success");
                response.setResult(true);
            }
        }
        if (null != nextHandler) {
            nextHandler.handler(context);
        }
    }

    @Override
    public int order(String taskType) {
        return this.order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    @Override
    public AbstractJesticChainHandler<ServerHearBeatRequest, ServerHearBeatResponse> setOrder(int order) {
        return null;
    }


}
